iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
1

還記在寫引數Argument文章有寫到當前墜一個星符號*的會得到陣列
那換成兩個星號呢**?今天就來認識單星星與雙星星吧!

*single splat

符號*single splat利用方法來看,結果會得到一個空的[]Array,它會將未指定的引數會被集合起來轉成一組陣列。

def splat(*single splat)
  single splat
end

p splat # []

利用最簡單的例子來看

a, b = [1, 2]
> a	# => 1
> b	# => 2

# a,b只會拿到陣列中前兩個值
a, b = [1, 2, 3, 4] 
> a	# => 1
> b	# => 2

# 可是當我們加上*
a, *other = [1, 2, 3, 4] 
> a		# => 1
> other	# => [2, 3, 4]

從方法看

多個引觀察輸出結果,*會把所有接收到的引數裝在一個陣列裡。

def say_hello(*students)
  students.each { |student| puts "Hi, #{student}" }
end

say_hello("Ruby","Sophia","Dora","Webber","Jimmy","Nina")

#  Hi, Ruby
#  Hi, Sophia
#  Hi, Dora
#  Hi, Webber
#  Hi, Jimmy

當我們拿到一筆資料,我們可以利用*轉Array格式

def my_pet(*pet)
  p pet
end
my_pet :cat, 15, name: :Meeks # [:cat, 15, {:name=>:Meeks}]

也可以將陣列反轉成清單

def say_hello(child, friend)
  puts "Hello, #{friend}. My name is #{child}"
end

name = %w(Sophia Nina)      # Hello, Nina. My name is Sophia.
name = %w(Sophia Nina Amy)  # ArgumentError
say_hello *name

此時在轉換的過程,必須要注意陣列元素的數量,否則會噴出ArgumentError的錯誤訊息喔!

**double splat

符號**double splat利用方法來看,結果會得到一個空的{}Hash

def splat(**double_splat)
  double_splat
end

p splat # {}

此時我就有些疑問了,它是不是跟陣列一樣,專門收未指定的引數呢?
我們從以下例子來看

def splat(a, **h)
  [a, h]
end

p splat(0)               # [0, {}]
p splat(0, 1)            # ArgumentError
p splat(0, a: 1)         # [0, {:a=>1}]
p splat(0, a: 1, b: 2)   # [0, {:a=>1, :b=>2}]

有發現嗎?當引數a: 1是一個key與value的組合為hash時,它就可以往**裡面塞了
如果位指定的引數不是hash則會出現ArgumentError

那如過全部混在一起呢?

def splat(a, *b, **c)
  [a, b, c]
end

p splat(0, 1, 2, 3, a: 4, b: 5, c: 6)
p splat(0, a: 4, b: 5, c: 6, 1, 2, 3)

# [0, [1, 2, 3], {:a=>4, :b=>5, :c=>6}]
# syntax error

第二行引數內容是一樣的,不過我將它位置順序調換,發現換位置之後出現syntax error的錯誤訊息,所以之後在使用時注意順序喔!

參考連結:
Ruby面試精選30題 - Day28 Ruby的 ** (double splat) operator


上一篇
Day15 | attr_reader . attr_writer . attr_accessor
下一篇
Day17 | namespace ::
系列文
從色彩繽紛到只看亂碼日子,學程式從 Ruby 出發!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言